<?php
$loader->requireOnce('ordo/Country.class.php');
$loader->requireOnce('ordo/Insurance.class.php');
$loader->requireOnce('ordo/Career.class.php');
$loader->requireOnce('ordo/QueueItem.class.php');
$loader->requireOnce('includes/DynamicMenu.class.php');
$loader->requireOnce('includes/PatientQueue/AbsQueue.class.php');
$loader->requireOnce('includes/OutPatientFlow/OutPatientFlowProcessor.class.php');
/**
 * Controller HIS Patient actions
 */
class C_Patient extends Controller {

	const DEFAULT_PROVINCE = 29; // Ho Chi Minh
	const DEFAULT_DISTRICT = 1; // District 1
	const DEFAULT_COUNTRY = 1; // Vietnamese
	var $_db;

    function C_Patient ($template_mod = "general") {
        parent::Controller();
        $this->_db = $GLOBALS['frame']['adodb']['db'];
    	if (Celini::getCurrentController() == 'Patient') {
			$menu =& Menu::getInstance();
			$menu->currentSection = 'patient';
		}
        $this->template_mod = $template_mod;
        $this->view->path = 'patient';
    }

    public function actionAddPatient(){
    	$menuObj = new DynamicMenu($this->_me);
		$result = $menuObj->processAddPatientMenuItem();

		if ($result !== false) {
			Celini::redirect($result['controller'], $result['action']);
		}
    }

    public function actionAddOutPatient() {
    	$provinceList =& ORDataObject::factory('Province')->getProvinceList();
        $countryList = ORDataObject::factory('Country')->getCountryListForSelect();
        $careerList	= $this->getCareerList();

       	$this->assign('provinceList', $provinceList);
        $this->assign('countryList', $countryList);
        $this->assign('careerList', $careerList);
        $this->assign('FORM_ACTION', Celini::link('addDemographics'));

        //@LOCALIZATION
        $orders	=	L10nHelper::getYMDorder();
        $this->assign('datePart_0', $orders[0]);
        $this->assign('datePart_1', $orders[1]);
        $this->assign('datePart_2', $orders[2]);
        return $this->view->render("add_demographics.html");
    }

    public function actionAddDemographics() {
    	//Sanitize first
    	$_POST['person']['name'] = Utils::sanitizeAndCaseTitle($_POST['person']['name']);
    	$_POST['address']['street'] = Utils::sanitizeAndCaseTitle($_POST['address']['street']);
    	$_POST['patient']['relative_name'] = Utils::sanitizeAndCaseTitle($_POST['patient']['relative_name']);
    	$_POST['patient']['relative_address'] = Utils::sanitizeAndCaseTitle($_POST['patient']['relative_address']);
    	$_POST['address']['ward_name'] =	Utils::sanitizeWard($_POST['address']['ward_name']);

    	// Add address first to get address_id
    	$address =& ORDataObject::factory('Address');
        $address->populateArray($_POST['address']);
    	$address->persist();

    	// Medical insurance registered hospital
    	if(isset($_POST['registeredHospital']) && !empty($_POST['registeredHospital'])){
    		$hospitalName	=	Utils::sanitizeAndCaseTitle($_POST['registeredHospital']);
    		if(!empty($hospitalName)){
    			$hospital	=	&ORDataObject::factory('Hospital');
    			
    			$hospitalId	=	$hospital->getIdFromName($hospitalName);
    			if($hospitalId > 0){
    				$_POST['insurance']['registered_hospital_id']	=	$hospitalId;
    			}
    			else{
    			    // TODO localization ptnguyen
    			    // Dont create new record if hospital name is not in database
    			    
    			    $_POST['insurance']['registered_hospital_id']    =   0;
    			}
    		}
    	}

    	// Then add person to get person_id & add patient
    	$person =& ORDataObject::factory('Person');
    	$_POST['person']['address_id'] = $address->getId();

    	$dates['year']	=	(int)Utils::sanitizeText($_POST['person']['DOB_yyyy']);
    	$dates['month']	=	(int)Utils::sanitizeText($_POST['person']['DOB_mm']);
    	$dates['day']	=	(int)Utils::sanitizeText($_POST['person']['DOB_dd']);
    	$_POST['person']['date_of_birth']	=	L10nHelper::getISODate($dates);

    	$person->populateArray($_POST['person']);
    	$person->persist();

    	// Add patient
    	$patient =& ORDataObject::factory('Patient');
    	$patientId = $person->getId();
    	$_POST['patient']['person_id'] =  $patientId;
    	$_POST['patient']['patient_code'] = $patient->genCode();
    	$patient->populateArray($_POST['patient']);
    	$patient->persist();

    	// Last add insurance to get insurance_id if any
    	if (isset($_POST['insurance']) && ($_POST['insurance']['insurance_code'] != '')) {
    		$insurance=& ORDataObject::factory('Insurance');

    		$issuedDate['year']		=	(int)Utils::sanitizeText($_POST['insurance']['issued_yyyy']);
    		$issuedDate['month']	=	(int)Utils::sanitizeText($_POST['insurance']['issued_mm']);
    		$issuedDate['day']		=	(int)Utils::sanitizeText($_POST['insurance']['issued_dd']);
    		$_POST['insurance']['date_issued']	=	L10nHelper::getISODate($issuedDate);

    		$expiredDate['year']	=	(int)Utils::sanitizeText($_POST['insurance']['expired_yyyy']);
    		$expiredDate['month']	=	(int)Utils::sanitizeText($_POST['insurance']['expired_mm']);
    		$expiredDate['day']		=	(int)Utils::sanitizeText($_POST['insurance']['expired_dd']);
    		$_POST['insurance']['date_expired']	=	L10nHelper::getISODate($expiredDate);
    		$_POST['insurance']['patient_id'] = $patientId;
    		$insurance->populateArray($_POST['insurance']);
    		$insurance->persist();
    	}

    	$nextAction = "";
    	if (isset($_POST['addDemographicsAndService'])) {
    		$nextAction = "service";
    	}

    	Celini::redirect('Patient', 'ViewMedicalRecord', array($patientId, $nextAction));
    }

    public function actionEditDemographicsAjax() {
		$response	=	'';
    	//Sanitize first
    	$_GET['person']['name'] = Utils::sanitizeAndCaseTitle($_GET['person']['name']);
    	$_GET['address']['street'] = Utils::sanitizeAndCaseTitle($_GET['address']['street']);
    	$_GET['patient']['relative_name'] = Utils::sanitizeAndCaseTitle($_GET['patient']['relative_name']);
    	$_GET['patient']['relative_address'] = Utils::sanitizeAndCaseTitle($_GET['patient']['relative_address']);
    	$_GET['address']['ward_name']		 =	Utils::sanitizeWard($_GET['address']['ward_name']);
    	// person
    	$personId = $_GET['person']['person_id'];

    	$person = ORDataObject::factory('Person', $personId);

    	$dates['year']	=	(int)Utils::sanitizeText($_GET['person']['DOB_yyyy']);
    	$dates['month']	=	(int)Utils::sanitizeText($_GET['person']['DOB_mm']);
    	$dates['day']	=	(int)Utils::sanitizeText($_GET['person']['DOB_dd']);
    	$_GET['person']['date_of_birth']	=	L10nHelper::getISODate($dates);

    	$person->populateArray($_GET['person']);
    	$response['personSaved'] = $person->persist();

    	//address
    	$address = ORDataObject::factory('Address', $person->get('address_id'));
        $address->populateArray($_GET['address']);
    	$address->persist();

    	// patient
    	$patient = ORDataObject::factory('Patient', $personId);
    	$patient->populateArray($_GET['patient']);
    	$patient->persist();

    	// Last add insurance to get insurance_id if any
    	$ins = Insurance::fromPatientId($personId);
    	$insId	=	$ins->get_id();
    	if($insId > 0 || (isset($_GET['insurance']) && ($_GET['insurance']['insurance_code'] != ''))){
	    	// Medical insurance registered hospital
	    	$_GET['insurance']['registered_hospital_id']	=	0;
    		if(isset($_GET['registeredHospital']) && !empty($_GET['registeredHospital'])){
	    		$hospitalName	=	Utils::sanitizeAndCaseTitle($_GET['registeredHospital']);
	    		if(!empty($hospitalName)){
	    			$hospital	=	&ORDataObject::factory('Hospital');
	    			$hospitalId	=	$hospital->getIdFromName($hospitalName);
	    			if($hospitalId > 0){
	    				$_GET['insurance']['registered_hospital_id']	=	$hospitalId;
	    			}
	    			else{
	    		    // TODO localization ptnguyen
                    // Dont create new record if hospital name is not in database
                    
                        $_POST['insurance']['registered_hospital_id']    =   0;
	    			}
	    		}
	    	}
	    	// @LOCALIZATION

	    	$issuedDate['year']		=	(int)Utils::sanitizeText($_GET['insurance']['issued_yyyy']);
    		$issuedDate['month']	=	(int)Utils::sanitizeText($_GET['insurance']['issued_mm']);
    		$issuedDate['day']		=	(int)Utils::sanitizeText($_GET['insurance']['issued_dd']);
    		$_GET['insurance']['date_issued']	=	L10nHelper::getISODate($issuedDate);

    		$expiredDate['year']	=	(int)Utils::sanitizeText($_GET['insurance']['expired_yyyy']);
    		$expiredDate['month']	=	(int)Utils::sanitizeText($_GET['insurance']['expired_mm']);
    		$expiredDate['day']		=	(int)Utils::sanitizeText($_GET['insurance']['expired_dd']);
    		$_GET['insurance']['date_expired']	=	L10nHelper::getISODate($expiredDate);

	    	$_GET['insurance']['patient_id'] = $personId;
	    	$ins->populateArray($_GET['insurance']);
	    	$ins->persist();
    	}
    	if($response['personSaved']){
    		$response['patientName']	=	$person->getName();
    		// TODO: @LOCALIZATION
    		$response['patientDob'] = L10nHelper::_('%s (%s Age)',$person->getDateofBirth(), $person->getAge());
    	}

    	echo json_encode($response);
    }

    public function actionAddIssueAjax() {
    	$patientId = $_POST['patientId'];
    	$patientIssue = Celini::newORDO('PatientMedicalAgent');
    	if ($patientIssue->getId($patientId, $_POST['issueName']) == 0) {
    		$patientIssue->addNewIssue($patientId, $_POST['issueName'], $_POST['issueValue'], $this->_me->get_person_id());
    		$this->buildAddIssueResponse($patientIssue);
    	} else {
    		echo 0;
    	}
    }

	public function actionDeleteIssueAjax() {
    	$patientIssue = Celini::newORDO('PatientMedicalAgent');
    	$patientIssue->deleteIssue($_GET["patientIssueId"]);
    }

    private function buildAddIssueResponse($patientIssue) {
    	$patientIssueId = $patientIssue->get('id');
    	$response = "<tr id='$patientIssueId'>
    					<td valign='top'>" . ORDataObject::factory('MedicalAgent')->getIssueNameFromId($patientIssue->get('medical_agent_id')) . "</td>" .
    				   "<td valign='top'>" . $patientIssue->getRealPersistenceInfo() . "</td>
    					<td valign='top'>" .$patientIssue->getUpdaterName() . "</td>
    					<td valign='top'>" .$patientIssue->getUpdated() . "</td>
    					<td valign='top' class='action'>
    	           			<a class='imgBtn' href='javascript:deleteIssue($patientIssueId)'>
    	           			<img title='Remove issue' src='../images/remove_small.png'/></a>
    	           		</td>";
    	echo $response;
    }

	public function actionViewMedicalRecord($patientId = 0, $nextAction = "", $canEditEncounter = 0) {
		if ($patientId == 0 && isset($_GET['patientId'])) {
			$patientId = $_GET['patientId'];
		}
		if ($nextAction == "" && isset($_GET['display'])) {
			$nextAction = $_GET['display'];
		}

		$person = Celini::newORDO('Person', $patientId);
		$patient = Celini::newORDO('Patient', $patientId);

		$this->assign('patientName', $person->get('name'));
		$this->assign('patientCode', $patient->get('patient_code'));
		// TODO: @LOCALIZATION
		$this->assign('patientDob', $person->getDateofBirth());
		// TODO: @LOCALIZATION
		$this->assign('patientAge', $person->getAge());
		// TODO: @LOCALIZATION
		$this->assign('lastExam', $patient->getLastExamDate());
   		$this->assign('display', $nextAction);
    	$this->assign('patientId', $patientId);
    	
    	$this->assign('canEditEncounter', $canEditEncounter);
    	return $this->view->render("view_medicalRecord.html");
    }

	public function actionStartEncounter($ticketItemId, $display) {
		// move to inprogress queue
		$result = AbsQueue::moveTicketItemToQueue($ticketItemId, AbsQueue::IN_PROGRESS);

		// set holder to the queue_item
		$user = $this->_me->get_user();
		$qi = QueueItem::fromTicketItemId($ticketItemId);
		$qi->set('holder_id', $user->get('person_id'));
		$qi->persist();

		// set doctor_id to ticket_item
		$ticketItem = Celini::newORDO('TicketItem', $ticketItemId);
		$ticketItem->set('doctor_id', $user->get('person_id'));
		$ticketItem->persist();

		// start ticket_item
		$ticketItem->start($ticketItemId);

		// get PatientId and render the encounter page
		$compositeServiceId = $ticketItem->get('item_id');
		$nextAction = $_GET['display'];
		$canEditEncounter = Celini::newORDO('EncounterTypeServiceMap')->getEncounterType($compositeServiceId);
		$patientId = $ticketItem->getPatientFromTicketItem($ticketItemId);

		Celini::redirect('Patient', 'ViewMedicalRecord', array($patientId, $nextAction, $canEditEncounter));
    }

    public function actionViewProgressEncounter($patientId = 0, $nextAction = "", $ticketItemId = 0) {
    	$ticketItem   =   Celini::newORDO('TicketItem', $ticketItemId);
		$ticketId     =   $ticketItem->get('ticket_id');
    	//$serviceId = $ticketItem->get('item_id');
		// FIXME: EMR Loader has changed, it's loaded by department
		// $canEditEncounter = Celini::newORDO('EncounterTypeServiceMap')->getEncounterType($serviceId);
		$canEditEncounter = 1;
		$patientId = $ticketItem->getPatientFromTicketItem($ticketItemId);
		// FIXME: why does $_GET['display'] come here?
		return $this->actionViewMedicalRecord($patientId, $_GET['display'], $canEditEncounter);
    }

    public function actionLoadDemographicsPage() {
    	$patientId = $_GET['patientId'];
    	$person = ORDataObject::factory('Person');
    	$person->setup($patientId);

    	$patient = ORDataObject::factory('Patient');
    	$patient->setup($patientId);

    	$insurance = Insurance::fromPatientId($patientId);
		$provinceList =& ORDataObject::factory('Province')->getProvinceList();
		$districtList =& ORDataObject::factory('District')->getDistrictList($person->getProvinceId());
		$districtCount = count($districtList);
		$wokingDistrictList	=	& ORDataObject::factory('District')->getDistrictList($person->getWorkingProvinceId());
    	$countryList = ORDataObject::factory('Country')->getCountryListForSelect();
		$countList = count($wokingDistrictList);
		$careerList	= $this->getCareerList();

    	$this->assign_by_ref('person', $person);
    	$this->assign_by_ref('patient', $patient);
    	$this->assign_by_ref('insurance', $insurance);
    	$this->assign('provinceList', $provinceList);
    	$this->assign('wokingDistrictList', $wokingDistrictList);
        $this->assign('districtList', $districtList);
        $this->assign('countryList', $countryList);
        $this->assign('nationality', $person->getNationalityObject());
        $this->assign('career', $person->getCareerObject());
        $this->assign('districtCount', $districtCount);
        $this->assign('countList', $countList);
        $this->assign('careerList', $careerList);

        //@LOCALIZATION
        $orders	=	L10nHelper::getYMDorder();
        $this->assign('datePart_0', $orders[0]);
        $this->assign('datePart_1', $orders[1]);
        $this->assign('datePart_2', $orders[2]);
        $birthDay	=	$person->getLocalizedDate('date_of_birth');
        $insIssued	=	$insurance->getLocalizedDate('date_issued');
        $insExpired	=	$insurance->getLocalizedDate('date_expired');

        $this->assign('birthDays', L10nHelper::getDateParts($birthDay));
        $this->assign('issuedDate', L10nHelper::getDateParts($insIssued));
        $this->assign('expiredDate', L10nHelper::getDateParts($insExpired));

        echo $this->view->render("view_demographics.html");
    }

    public function actionGetDistrictFromProvinceAjax() {
    	$districtList=& ORDataObject::factory('District')->getDistrictList($_GET['provice_id']);
    	$response['districtList'] = "";
    	$districtId = 0;
    	foreach ($districtList as $key=>$value) {
    		if ($districtId == 0) {
    			$districtId	= $key;
    		}
			$response['districtList'] .= "<option value=\"$key\">$value</option>";
		}
		echo json_encode($response);
    }

	public function actionGetWardFromDistrictAjax() {
		// @LOCALIZATION
		$column		= 	$_GET['column'];
		$filter		=	$_GET['filter'];
		$response	=	array();
		$field		=	L10nHelper::changeField(L10nHelper::getLocale(), 'name');
		
		$sql		=	"SELECT t.$field as name
		                    FROM ward t
						    WHERE t.$column = $filter";
		$res		=	$this->_db->Execute($sql);
		while($res && !$res->EOF){
			$response[] = $res->fields['name'];
			$res->MoveNext();
		}
		echo json_encode($response);
    }

    private function getBaseUri() {
    	$proto = Utils::getProtocol();
    	return $proto . $_SERVER['SERVER_NAME'] . $this->base_dir;
    }

    public function getCareerList() {
    	$careerList	=&	ORDataObject::factory('Career')->getCareerListForSelect();
        $orderedCareerList = array();
        $temp = array();
        $joblessId = Career::JOBLESS;
        foreach ($careerList as $id=>$name) {
        	if ($id != $joblessId) {
        		$orderedCareerList[$id] = $name;
        	} else {
        		$temp[$id] = $name;
        	}
        }
        if(!empty($temp)){
        	$orderedCareerList[$joblessId] = $temp[$joblessId];
        }
        return $orderedCareerList;
    }

    // TODO: ptnguyen 2010-02-17
    // Move sql code to ordo
    public function actionGetHospitalSuggestionAjax(){
    	$field	=	L10nHelper::changeField(L10nHelper::getLocale(), 'name');
    	if(isset($_GET['part']) && $_GET['part']!=''){
			$part		=	$_GET['part'];
			$response	=	array();
			$sql	=	"SELECT t.$field as name
			             FROM hospital t
				         WHERE t.$field like '%$part%'
				         LIMIT 10";
			$res	=	$this->_db->Execute($sql);
			while($res && !$res->EOF){
				$response[] = $res->fields['name'];
				$res->MoveNext();
			}
			echo json_encode($response);
		}
    }

}
?>